package com.hospital.schedule.module.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hospital.common.dto.schedule.module.AddDoctorAttendanceDto;
import com.hospital.common.enums.schedule.module.HourSlotType;
import com.hospital.common.pojo.TDoctorAttendance;
import com.hospital.common.pojo.TDoctorSchedule;
import com.hospital.common.utils.TimeUtils;
import com.hospital.schedule.module.exception.DoctorAttendanceException;
import com.hospital.schedule.module.exception.enums.DoctorAttendanceExceptionEnum;
import com.hospital.schedule.module.mapper.TDoctorAttendanceMapper;
import com.hospital.schedule.module.service.ITDoctorAttendanceService;
import com.hospital.schedule.module.service.ITDoctorScheduleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * <p>
 * 医⽣考勤记录表 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-09-15
 */
@Service
public class TDoctorAttendanceServiceImpl extends ServiceImpl<TDoctorAttendanceMapper, TDoctorAttendance> implements ITDoctorAttendanceService {

    @Autowired
    private TDoctorAttendanceMapper tDoctorAttendanceMapper;
    @Autowired
    private ITDoctorScheduleService iTDoctorScheduleService;

    @Override

    public synchronized Integer addDoctorAttendance(Long userId) {
        TDoctorAttendance tDoctorAttendance = new TDoctorAttendance();
        tDoctorAttendance.setDoctorId(userId);// 医生id
        AddDoctorAttendanceDto addDoctorAttendanceDto = new AddDoctorAttendanceDto();
        addDoctorAttendanceDto.setDoctorId(userId);
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String currentTime = now.format(formatter);
        addDoctorAttendanceDto.setStartTime(TimeUtils.formatToStartOfDay(currentTime));
        addDoctorAttendanceDto.setEndTime(currentTime);

        List<TDoctorAttendance> tDoctorAttList = tDoctorAttendanceMapper.findDoctorAttendanceByNow(addDoctorAttendanceDto);
        if(tDoctorAttList != null && tDoctorAttList.size() > 0) {
            // 如果有多条记录，说明已经完成至少一次完整考勤
            if(tDoctorAttList.size() > 1) {
                throw new DoctorAttendanceException(DoctorAttendanceExceptionEnum.HAS_ATTENDANCE);
            }

            // 如果只有一条记录，检查是否已完成签退
            if(tDoctorAttList.size() == 1 && tDoctorAttList.get(0).getCheckOutTime() != null) {
                throw new DoctorAttendanceException(DoctorAttendanceExceptionEnum.HAS_ATTENDANCE);
            }
        }



        TDoctorAttendance tDoctorAtt = tDoctorAttList.size()>0?tDoctorAttList.get(0):null;

        addDoctorAttendanceDto.setEndTime(TimeUtils.formatToEndOfDay(currentTime));
        List<TDoctorSchedule> tDoctorScheduleList = iTDoctorScheduleService
                .findDoctorScheduleByAttend(addDoctorAttendanceDto);
        if(tDoctorScheduleList==null || tDoctorScheduleList.size() == 0){
            throw new DoctorAttendanceException(DoctorAttendanceExceptionEnum.ADD_FAIL);
        }
        List<Long> doctorScheduleIdList = tDoctorScheduleList.stream()
                .map(TDoctorSchedule::getId).toList();
        tDoctorAttendance.setScheduleId(JSONUtil.toJsonStr(doctorScheduleIdList));//Jso字符串存储排班id
//        // 还原为 JSONArray
//        JSONArray jsonArray = JSONUtil.parseArray(JSONUtil.toJsonStr(doctorScheduleIdList));
//
//// 转换为 List<Long>
//        List<Long> doctorScheduleIdList = jsonArray.toList(Long.class);
//        tDoctorAttendance.setCheckInTime(LocalDateTime.now());//签到时间或者签退时间
//        tDoctorAttendance.setRecordTime(now);
        if(tDoctorAtt == null){
            String endTime = TimeUtils.getStartDateTimeWithToday(HourSlotType.fromCode(tDoctorScheduleList.get(0).getHourSlot()));
            boolean compare = TimeUtils.compareDateString(currentTime, endTime);
            tDoctorAttendance.setCheckInTime(LocalDateTime.now());
            if(compare){
                tDoctorAttendance.setAttendanceStatus(1);//签到状态，1正常
            }else{
                tDoctorAttendance.setAttendanceStatus(0);//签到状态，0迟到
            }
            tDoctorAttendance.setRecordTime(now);
            tDoctorAttendanceMapper.addDoctorAttendance(tDoctorAttendance);
        }else{
            String endTime = TimeUtils.getEndDateTimeWithToday(HourSlotType
                    .fromCode(tDoctorScheduleList.get(tDoctorScheduleList.size()-1).getHourSlot()));
            boolean compare = TimeUtils.compareDateString(endTime, currentTime);
            if(compare){
                if(tDoctorAttList.get(0).getAttendanceStatus()!=1){
                    tDoctorAttendance.setAttendanceStatus(tDoctorAttList.get(0).getAttendanceStatus());
                }else{
                    tDoctorAttendance.setAttendanceStatus(1);//签到状态，1正常
                }

            }else{
                tDoctorAttendance.setAttendanceStatus(2);//签到状态，2早退
            }
            tDoctorAttendance.setId(tDoctorAtt.getId());
            tDoctorAttendance.setCheckOutTime(LocalDateTime.now());
            tDoctorAttendanceMapper.updateDoctorAttendance(tDoctorAttendance);
        }

        return null;
    }

    @Override
    public Integer inspectAttendance() {
        long ms = System.currentTimeMillis();
        String inputTime = TimeUtils.longDataTimeString(ms);
        System.out.println("inputTime = " + inputTime);
        String formatToStartOfDay = TimeUtils.formatToStartOfDay(inputTime);
        System.out.println("formatToStartOfDay = " + formatToStartOfDay);
        String formatToEndOfDay = TimeUtils.formatToEndOfDay(TimeUtils.longDataTimeString(System.currentTimeMillis()));

        List<Long> doctorIdList = iTDoctorScheduleService.findDoctorId(formatToEndOfDay,formatToStartOfDay);
        if(doctorIdList!=null && doctorIdList.size()>0){
            List<Long> doctorIds = tDoctorAttendanceMapper.inspectAttendance(doctorIdList,formatToEndOfDay,formatToStartOfDay);
            if(doctorIds!=null && doctorIds.size()>0){
                for (Long doctorId : doctorIds) {
                    tDoctorAttendanceMapper.addAbsence(doctorId);
                }

            }
            tDoctorAttendanceMapper.updateOnNotCheckOutTime();
        }
        return null;
    }

    @Override
    public Integer findIfDoctorAttendanceByNow(Long doctorId) {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String currentTime = now.format(formatter);
        String formatToStartOfDay = TimeUtils.formatToStartOfDay(currentTime);
        String formatToEndOfDay = TimeUtils.formatToEndOfDay(currentTime);
        Long ifDoctorAttendanceByNow = tDoctorAttendanceMapper.findIfDoctorAttendanceByNow(doctorId,formatToStartOfDay,formatToEndOfDay);

        return ifDoctorAttendanceByNow==null?0:1;
    }

    @Override
    public Integer isEarlyLeave(Long doctorId) {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String currentTime = now.format(formatter);
        String formatToStartOfDay = TimeUtils.formatToStartOfDay(currentTime);
        String formatToEndOfDay = TimeUtils.formatToEndOfDay(currentTime);
        AddDoctorAttendanceDto addDoctorAttendanceDto = new AddDoctorAttendanceDto();
        addDoctorAttendanceDto.setDoctorId(doctorId);
        addDoctorAttendanceDto.setStartTime(formatToStartOfDay);
        addDoctorAttendanceDto.setEndTime(formatToEndOfDay);
        Integer ifDoctorAttendanceByNow = this.findIfDoctorAttendanceByNow(doctorId);
        if(ifDoctorAttendanceByNow==0){
            return 0;
        }else{
            List<TDoctorSchedule> tDoctorScheduleList = iTDoctorScheduleService
                    .findDoctorScheduleByAttend(addDoctorAttendanceDto);
            if(tDoctorScheduleList==null || tDoctorScheduleList.size() == 0){
                throw new DoctorAttendanceException(DoctorAttendanceExceptionEnum.ADD_FAIL);
            }
            String endTime = TimeUtils.getEndDateTimeWithToday(HourSlotType
                    .fromCode(tDoctorScheduleList.get(tDoctorScheduleList.size()-1).getHourSlot()));
            boolean compare = TimeUtils.compareDateString(endTime, currentTime);
            if(compare)
                return 0;
            else
                return 1;
        }
    }
}
